package edu.scu.declaresys.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import edu.scu.declaresys.config.Configs;
import edu.scu.declaresys.dao.DAOFactory;
import edu.scu.declaresys.dao.intr.IProjectDAO;
import edu.scu.declaresys.exception.ExecuteException;
import edu.scu.declaresys.util.PageList;
import edu.scu.declaresys.vo.Project;

public class ProjectDAOImpl extends GeneralDAOImpl<Project> implements
		IProjectDAO
{

	public ProjectDAOImpl()
	{
		super(Project.class);
	}

	@Override
	protected void fillReference(Project vo, int depth) throws ExecuteException
	{
		vo.setCity(DAOFactory.createAreaDAO().findById(vo.getAreaCityId(), depth - 1));
		vo.setCounty(DAOFactory.createAreaDAO().findById(vo.getAreaCountyId(), depth - 1));	
		vo.setProjectClass(DAOFactory.createProjectClassDAO().findById(vo.getProjectClassId(), depth-1));
		vo.setDeclareUser(DAOFactory.createUserDAO().findById(vo.getDeclareUserId(), depth-1));
		vo.setCountyRecUser(DAOFactory.createUserDAO().findById(vo.getCountyRecUserId(), depth-1));
		vo.setCityRecUser(DAOFactory.createUserDAO().findById(vo.getCityRecUserId(), depth-1));
		vo.setProvinceRecUser(DAOFactory.createUserDAO().findById(vo.getProvinceRecUserId(), depth-1));
		vo.setAuditUser(DAOFactory.createUserDAO().findById(vo.getAuditUserId(), depth-1));
	}

	@Override
	public PageList<Project> findByExcludeStates(Integer decUserId, Integer[] excludeStates, int depth, Integer pageNum, Integer amtPerPage, String orderColumn, Boolean isAsc) throws ExecuteException
	{
		Session session = getSession();
		PageList<Project> voLst = new PageList<Project>();
		Transaction trans = null;
		//
		try
		{
			trans = session.beginTransaction();
			Criteria criteria = session.createCriteria(Project.class);
			if(decUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_DECLARE_USER_ID, decUserId));
			}
			if(excludeStates != null && excludeStates.length != 0)
			{
				for(Integer state : excludeStates)
				{
					criteria.add(Restrictions.not(Restrictions.eq(Project.T_STATE, state)));
				}
			}
			super.dealPageAndOrder(criteria, depth, pageNum, amtPerPage, orderColumn, isAsc, voLst);
			trans.commit();
		}
		catch(RuntimeException re)
		{
			if(trans != null)
			{
				trans.rollback();
			}
			throw new ExecuteException(Configs.isDebug ? re.getMessage() : "");
		}
		finally
		{
			closeSession();
		}
		return voLst;
	}

	@Override
	public PageList<Project> findProject(Integer declareUserId, Integer countyRecUserId, Integer cityRecUserId,
			Integer provinceRecUserId, Integer auditUserId, 
			Integer[] states, Integer year, Integer projectClassId, String projectName, 
			int depth, 
			Integer pageNum, Integer amtPerPage, String orderColumn, Boolean isAsc)
	throws ExecuteException
	{
		
		Session session = getSession();
		PageList<Project> voLst = new PageList<Project>();
		//
		try
		{
			Criteria criteria = session.createCriteria(Project.class);
			if(declareUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_DECLARE_USER_ID, declareUserId));
			}
			if(countyRecUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_COUNTY_REC_USER_ID, countyRecUserId));
			}
			if(cityRecUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_CITY_REC_USER_ID, cityRecUserId));						
			}
			if(provinceRecUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_PROVINCE_REC_USER_ID, provinceRecUserId));
			}
			if(auditUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_AUDIT_USER_ID, auditUserId));
			}
			//state
			if(states != null && states.length != 0)
			{
				criteria.add(Restrictions.in(Project.T_STATE, states));
			}
			//year
			if(year != null)
			{
				criteria.add(Restrictions.eq(Project.T_YEAR, year));
			}
			//project class
			if(projectClassId != null)
			{
				criteria.add(Restrictions.eq(Project.T_PROJECT_CLASS_ID, projectClassId));
			}
			//project name
			if(projectName != null)
			{
				criteria.add(Restrictions.like(Project.T_NAME, projectName, MatchMode.ANYWHERE));
			}
			super.dealPageAndOrder(criteria, depth, pageNum, amtPerPage, orderColumn, isAsc, voLst);
		}
		catch(RuntimeException re)
		{
			throw new ExecuteException(Configs.isDebug ? "findProject" + re.getMessage() : "");
		}
		finally
		{
			closeSession();
		}
		return voLst;
	}

	@Override
	public PageList<Project> searchProject(Integer cityId, Integer countyId, Integer declareUserId,
			Integer projectClassId, Integer year, String projectName, Integer state,
			int depth, Integer pageNum, Integer amtPerPage,String orderColumn, Boolean isAsc)
	throws ExecuteException
	{
		Session session = getSession();
		PageList<Project> voLst = new PageList<Project>();
		//
		try
		{
			Criteria criteria = session.createCriteria(Project.class);
			if(cityId != null)
			{
				criteria.add(Restrictions.eq(Project.T_AREA_CITY_ID, cityId));
			}
			if(countyId != null)
			{
				criteria.add(Restrictions.eq(Project.T_AREA_COUNTY_ID, countyId));
			}
			if(declareUserId != null)
			{
				criteria.add(Restrictions.eq(Project.T_DECLARE_USER_ID, declareUserId));
			}
			if(projectClassId != null)
			{
				criteria.add(Restrictions.eq(Project.T_PROJECT_CLASS_ID, projectClassId));
			}
			if(year != null)
			{
				criteria.add(Restrictions.eq(Project.T_YEAR, year));
			}
			//project name
			if(projectName != null)
			{
				criteria.add(Restrictions.like(Project.T_NAME, projectName, MatchMode.ANYWHERE));
			}
			if(state != null)
			{
				criteria.add(Restrictions.eq(Project.T_STATE, state));
			}
			criteria.add(Restrictions.in(Project.T_STATE, new Integer[]{Project.STATE_PASSED, Project.STATE_REJECTED}));
			super.dealPageAndOrder(criteria, depth, pageNum, amtPerPage, orderColumn, isAsc, voLst);
		}
		catch(RuntimeException re)
		{
			throw new ExecuteException(Configs.isDebug ? re.getMessage() : "");
		}
		finally
		{
			closeSession();
		}
		return voLst;
	}
}
